package org.ljy.lotterysystem.service.activitystatus.impl;

import org.ljy.lotterysystem.common.errorcode.ServiceErrorCodeConstants;
import org.ljy.lotterysystem.common.exception.ServiceException;
import org.ljy.lotterysystem.service.IActivityService;
import org.ljy.lotterysystem.service.activitystatus.IActivityStatusManager;
import org.ljy.lotterysystem.service.activitystatus.operater.AbstractActivityOperator;
import org.ljy.lotterysystem.service.dto.ConvertActivityStatusDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Service
public class ActivityStatusManagerImpl implements IActivityStatusManager {


    private static final Logger logger = LoggerFactory.getLogger(ActivityStatusManagerImpl.class);

    @Autowired
    private Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();


    @Autowired
    private IActivityService activityService;

    /**
     * 扭转状态 -- 策略模式保证执行的顺序
     * @param convertActivityStatusDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        if(CollectionUtils.isEmpty(operatorMap)) {
            logger.warn("operatorMap is empty");
            return;
        }
        Map<String, AbstractActivityOperator> currMap = new HashMap<>(operatorMap);
        Boolean update = false;
        //1.先处理人员、奖品
        update = processConvertStatus(convertActivityStatusDTO,currMap,1);
        //2.在处理活动
        update = processConvertStatus(convertActivityStatusDTO,currMap,2) || update;
        //3.更新缓存
        if(update) {
            //将新的状态新的缓存更新进去，替换原来旧的
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }

    }

    /**
     * 回滚状态
     * @param statusConvertDTO
     */
    @Override
    public void rollbackHandlerEvent(ConvertActivityStatusDTO statusConvertDTO) {

        //1.修改map中对象的状态
        for(AbstractActivityOperator operator : operatorMap.values()) {
            operator.convert(statusConvertDTO);//修改状态
        }
        //2.更新缓存
        activityService.cacheActivity(statusConvertDTO.getActivityId());
    }


    /**
     *  真正扭转状态
     * @param convertActivityStatusDTO
     * @param currMap
     * @param sequance
     * @return
     */
    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> currMap,
                                         int sequance) {
        Boolean update = false;
        //遍历currMap
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = currMap.entrySet().iterator();
        while(iterator.hasNext()) {
            AbstractActivityOperator operator = iterator.next().getValue();
            //Operator是否需要转换
            if(operator.sqquance() != sequance
                    || !operator.needConvert(convertActivityStatusDTO)) {
                continue;//不需要转换
            }
            //需要转换：转换
            if( !operator.convert(convertActivityStatusDTO)) {
                logger.warn("{} 状态转化失败！",operator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.STATUS_CONVERT_ERROR);
            }
            //currMap 删除当前Operator
            iterator.remove();
            update = true;
        }
        //返回
        return update;
    }
}
